/**
 * @author DongPing
 * 2022/1/20 20:07
 *
 * 带分页和搜索的下拉选择组件
 *
 * */
import {ChangeEvent, useCallback, useEffect, useRef, useState} from "react";
import {Button, Input, Pagination, Table} from "antd";
import {TSelectOptions} from "@/common-data-source/type";
require('./PageSelector.less');

export type TPageSelectorSearchParams = {pageSize: number, pageNo: number, keyWord: string}

export function PageSelector(props: {
	value: string,
	onChange: (value: string, name: string) => void,
	disabled?: boolean
	// 查询选项数据
	dataSource: (searchParams: TPageSelectorSearchParams) => Promise<{data: TSelectOptions, total: number}>,
	// 选项数据里面用来做value的那个属性的名称
	valueAttributeName?: string,
	// 选项数据里面用来做name的那个属性名称
	nameAttributeName?: string,
	tableColumns?: Array<{title: string, attributeName: string}>
}) {
	const pageSize = 5;
	const {value, onChange, disabled, valueAttributeName = 'value', dataSource,
		nameAttributeName = 'name',
		tableColumns = [{title: '编码', attributeName: 'value'}, {title: '名称', attributeName: 'name'}]
	} = props;
	const [data, setData] = useState<any[]>([]);
	const [total, setTotal] = useState(0);
	const [current, setCurrent] = useState(1);
	const [searchKeyWord, setSearchKeyWord] = useState<string>();
	const [searchMode, setSearchMode] = useState(false);
	const rootElRef = useRef<HTMLDivElement | null>(null);

	let matchedItem = data.find((item) => item[valueAttributeName] === value);
	let matchedName = matchedItem ? matchedItem[nameAttributeName] : '';

	const [left, setLeft] = useState(0);
	const [top, setTop] = useState(0);
	// 根据组件当前位置计算选择框的位置
	function updateSelectAreaPosition() {
		const rootEl = rootElRef.current;
		if(!rootEl) return;
		const rect = rootEl.getBoundingClientRect();
		setLeft(rect.x);
		setTop(rect.bottom);
	}

	function queryData(page: number, keyWord?: string) {
		dataSource({
			pageSize, pageNo: page, keyWord: typeof keyWord === 'string' ? keyWord : (searchKeyWord || '')
		})
			.then(({total, data}) => {
				setTotal(total);
				setData(data);
			})
	}
	useEffect(function () {
		queryData(current)
	}, []);

	useEffect(function () {
		// 如果选择项里面不包含 设置的值的那一项数据，查询options
		if(value && (!data.some((item) => item[valueAttributeName] === value))) {
			queryData(1, value);
		}
	}, [value]);

	// function onFocus() {
	// 	setSearchKeyWord('');
	// 	setSearchMode(true);
	// 	updateSelectAreaPosition();
	// }

	function onFocusInputClick() {
		setSearchKeyWord('');
		setSearchMode(true);
		updateSelectAreaPosition();
	}

	function onInputChange(e: ChangeEvent<HTMLInputElement>) {
		// 只有点击清除的时候改变值
		const v = e.target.value;
		if(v === '') {
			onChange(v, '');
		}
	}

	function onSearch() {
		queryData(1);
		setCurrent(1);
	}
	function onSearchAll() {
		setSearchKeyWord('');
		queryData(1, '');
		setCurrent(1);
	}
	function onClickRow(record: any) {
		onChange(record[valueAttributeName], record[nameAttributeName]);
		setSearchMode(false);
		setSearchKeyWord('');
	}

	let onDocumentClick = useCallback(function (e: any) {
		if(searchMode) {
			if(rootElRef.current && !hasParent(e.target, rootElRef.current)) {
				setSearchKeyWord('');
				setSearchMode(false);
			}
		}


	}, [searchMode]);
	useEffect(function () {
		document.addEventListener('click', onDocumentClick);
		return function () {
			document.removeEventListener('click', onDocumentClick)
		}
	}, [onDocumentClick]);

	return (
		<div ref={(el) => rootElRef.current = el} className={"select-table-optimized"}>
			{searchMode ?
				<Input autoFocus placeholder={matchedName} allowClear prefixCls={!!searchKeyWord ? 'have-clean-icon ant-input' : 'ant-input'} value={searchKeyWord} onChange={(e) => setSearchKeyWord(e.target.value)}/>
				:
				<Input allowClear disabled={disabled} prefixCls={!!matchedName ? 'have-clean-icon ant-input' : 'ant-input'} value={matchedName} onChange={onInputChange} onClick={onFocusInputClick}/>
			}
			{
				searchMode ?
					<div className={"select-area"} style={{top: top, left: left}}>
						<div className={"buttons"}>
							<Button type="primary" onClick={onSearch}>搜索</Button>
							<Button type={"primary"} onClick={onSearchAll}>显示全部</Button>
						</div>
						<Table
							size={"small"}
							pagination={false}
							dataSource={data}
							onRow={record => {
								return {
									onClick: () => {
										onClickRow(record);
									}
								};
							}}
						>

							{
								tableColumns.map((c) => <Table.Column title={c.title} dataIndex={c.attributeName} key={c.attributeName} />)
							}
						</Table>

						<div className={"pagination-wrapper"}>
							<Pagination size={"small"} total={total} current={current} pageSize={5} onChange={(page) => {
								queryData(page);
								setCurrent(page);
							}}/>
						</div>
					</div>
					:
					null
			}
		</div>
	)
}

export function hasParent(el: Element, parentEl: Element): boolean {
	const p = el.parentElement;
	if(!p) {
		return false;
	} else if(p === parentEl) {
		return true;
	} else if(p === document.body) {
		return false;
	} else {
		return hasParent(p, parentEl);
	}
}
